import java.util.List;

public class Test {
    public static void main(String[] args) {
        // 变量 i 在每次循环迭代都被 重新赋值 (++i)，因此它不是 effectively final。
        // Java 规定：Lambda 内部如果引用局部变量，该变量 必须自始至终只赋一次值。
        // 结果：编译器直接报错 “Local variable i is required to be final or effectively final”
        // for(int i= 0;i< 5; ++i) {
        // final int index = i;
        // Runnable r1 = ()->System.out.println("i is "+ i);
        // }
        for (int i = 0; i < 5; ++i) {
            // Lambda 只能捕获 final 或“事实 final”（effectively final）的局部变量。
            final int index = i;
            Runnable r1 = () -> System.out.println("i is " + index);
            r1.run();
        }

        for (int i = 0; i < 5; ++i) {
            // 不写也行，编译器自动推断
            int index = i;
            Runnable r1 = () -> System.out.println("i is " + index);
            r1.run();
        }

        // 这个例子中list1就是effectively final的
        List<Integer> list1 = List.of(1, 2, 5);
        for (int i = 0; i < 5; ++i) {
            Runnable r1 = () -> System.out.println(list1.toString());
            r1.run();
        }
    }

}

// java 没有 Rust 那种“显式 move / 默认借用的捕获模式”。
// 在 Java 里，所有被 Lambda（或匿名类）捕获的局部变量一律是“值拷贝”，编译器偷偷帮你放进隐藏字段；
// 对对象而言，拷贝的是引用值（地址），而不是对象本体。
// 因此：
// 基本类型：复制数值 → 后续外部怎么改都不影响捕获值。
// 引用类型：复制地址 → 内外指向同一对象，可以修改对象内部状态，但不能让引用重新指向另一个对象（否则失去 effectively final）。